<template>
  <div class="app-container">
    <el-form ref="queryForm" :model="queryParams" size="small" :inline="true" v-show="showSearch" label-width="80px">
      <el-form-item label="分类名称" prop="name">
        <el-input
          v-model="queryParams.name"
          placeholder="请输入分类名称"
          clearable
          style="width: 240px"
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item label="状态" prop="status">
        <el-select v-model="queryParams.status" placeholder="请选择状态" clearable style="width: 240px">
          <el-option
            v-for="option in statusOptions"
            :key="option.value"
            :label="option.label"
            :value="option.value"
          />
        </el-select>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
      </el-form-item>
    </el-form>

    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd">新增</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button type="success" plain icon="el-icon-edit" size="mini" :disabled="single" @click="handleUpdate">修改</el-button>
      </el-col>
      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList" />
    </el-row>

    <el-table
      v-loading="loading"
      :data="categoryList"
      row-key="id"
      :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
      border
      default-expand-all
      @selection-change="handleSelectionChange"
    >
      <el-table-column type="selection" width="55" align="center" />
      <el-table-column label="ID" align="center" prop="id" width="80" />
      <el-table-column label="分类名称" prop="name" min-width="200" show-overflow-tooltip />
      <el-table-column label="父级ID" prop="parent_id" width="120" align="center">
        <template slot-scope="scope">
          <span>{{ scope.row.parent_id || '-' }}</span>
        </template>
      </el-table-column>
      <el-table-column label="状态" prop="status" width="120" align="center">
        <template slot-scope="scope">
          <el-tag :type="getStatusTagType(scope.row.status)">{{ getStatusLabel(scope.row.status) }}</el-tag>
        </template>
      </el-table-column>
      <el-table-column label="图片" min-width="200" align="center">
        <template slot-scope="scope">
          <div v-if="scope.row.imageList && scope.row.imageList.length" class="image-preview">
            <el-image
              v-for="(img, index) in scope.row.imageList.slice(0, 3)"
              :key="img + index"
              :src="img"
              :preview-src-list="scope.row.imageList"
              fit="cover"
              class="image-preview__item"
            />
            <span v-if="scope.row.imageList.length > 3" class="image-preview__more">+{{ scope.row.imageList.length - 3 }}</span>
          </div>
          <span v-else>-</span>
        </template>
      </el-table-column>
      <el-table-column label="创建时间" prop="created_at" width="180" align="center">
        <template slot-scope="scope">
          <span>{{ scope.row.created_at ? parseTime(scope.row.created_at) : '-' }}</span>
        </template>
      </el-table-column>
      <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="180">
        <template slot-scope="scope">
          <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)">修改</el-button>
        </template>
      </el-table-column>
    </el-table>

    <pagination
      v-show="total > 0"
      :total="total"
      :page.sync="queryParams.page"
      :limit.sync="queryParams.pageSize"
      @pagination="getList"
    />

    <el-dialog :title="title" :visible.sync="open" width="600px" append-to-body>
      <el-form ref="form" :model="form" :rules="rules" label-width="100px">
        <el-form-item label="分类名称" prop="name">
          <el-input v-model="form.name" placeholder="请输入分类名称" />
        </el-form-item>
        <el-form-item label="状态" prop="status">
          <el-radio-group v-model="form.status">
            <el-radio v-for="option in statusOptions" :key="option.value" :label="option.value">{{ option.label }}</el-radio>
          </el-radio-group>
        </el-form-item>
      <el-form-item label="父级分类" prop="parent_id">
        <el-select
          v-model="form.parent_id"
          placeholder="请选择父级分类"
          clearable
          style="width: 100%"
        >
          <el-option
            v-for="option in parentOptions"
            :key="option.value"
            :label="option.label"
            :value="option.value"
          />
        </el-select>
        </el-form-item>
        <el-form-item label="分类图片" prop="image">
          <image-upload v-model="form.image" :limit="6" :file-size="5" />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" :loading="submitLoading" @click="submitForm">确 定</el-button>
        <el-button @click="cancel">取 消</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { getCategoryList, addCategory, updateCategory, deleteCategory } from '@/api/api'
import ImageUpload from '@/components/ImageUpload'

export default {
  name: 'Classify',
  components: { ImageUpload },
  data() {
    return {
      loading: false,
      submitLoading: false,
      showSearch: true,
      categoryList: [],
      parentOptions: [],
      statusOptions: [
        { label: '启用', value: "1" },
        { label: '禁用', value: "2" },
        { label: '隐藏', value: "3" }
      ],
      ids: [],
      single: true,
      multiple: true,
      total: 0,
      title: '',
      open: false,
      baseUrl: process.env.VUE_APP_BASE_API,
      queryParams: {
        page: 1,
        pageSize: 10,
        name: undefined,
        status: undefined
      },
      form: {
        id: undefined,
        name: '',
        status: "1",
        parent_id: undefined,
        image: ''
      },
      rules: {
        name: [
          { required: true, message: '分类名称不能为空', trigger: 'blur' },
          { min: 1, max: 50, message: '长度需在 1 到 50 个字符', trigger: 'blur' }
        ],
        status: [
          { required: true, message: '请选择状态', trigger: 'change' }
        ]
      }
    }
  },
  created() {
    this.getList()
  },
  methods: {
    getList() {
      this.loading = true
      getCategoryList(this.queryParams)
        .then(res => {
          const { list, total } = this.normalizeResponse(res)
          const tree = this.buildTree(list)
          this.categoryList = this.decorateCategories(tree)
          this.total = total || list.length
          this.parentOptions = this.getTopLevelOptions()
        })
        .finally(() => {
          this.loading = false
        })
    },
    normalizeResponse(res) {
      if (!res) {
        return { list: [], total: 0 }
      }
      if (Array.isArray(res)) {
        return { list: res, total: res.length }
      }
      if (Array.isArray(res.rows)) {
        return { list: res.rows, total: res.total ?? res.rows.length }
      }
      if (Array.isArray(res.data)) {
        return { list: res.data, total: res.total ?? res.data.length }
      }
      if (res.data && Array.isArray(res.data.records)) {
        return { list: res.data.records, total: res.data.total ?? res.data.records.length }
      }
      if (res.data && Array.isArray(res.data.list)) {
        return { list: res.data.list, total: res.data.total ?? res.data.list.length }
      }
      if (Array.isArray(res.list)) {
        return { list: res.list, total: res.total ?? res.list.length }
      }
      if (Array.isArray(res.records)) {
        return { list: res.records, total: res.total ?? res.records.length }
      }
      return { list: [], total: 0 }
    },
    buildTree(list = []) {
      const nodeMap = new Map()
      list.forEach(item => {
        if (!item || item.id === undefined || item.id === null) {
          return
        }
        const clone = { ...item, children: [] }
        nodeMap.set(clone.id, clone)
      })
      const roots = []
      nodeMap.forEach(node => {
        const parentId = node.parent_id
        if (parentId === null || parentId === undefined || parentId === '' || !nodeMap.has(parentId)) {
          roots.push(node)
        } else {
          const parent = nodeMap.get(parentId)
          parent.children = parent.children || []
          parent.children.push(node)
        }
      })
      return roots
    },
    decorateCategories(list = []) {
      return list.map(item => {
        const clone = { ...item }
        clone.imageList = this.normalizeImages(clone.image)
        if (Array.isArray(item.children) && item.children.length) {
          clone.children = this.decorateCategories(item.children)
        } else {
          delete clone.children
        }
        return clone
      })
    },
    flattenCategories(list = [], result = []) {
      list.forEach(item => {
        result.push(item)
        if (Array.isArray(item.children) && item.children.length) {
          this.flattenCategories(item.children, result)
        }
      })
      return result
    },
    handleQuery() {
      this.queryParams.page = 1
      this.getList()
    },
    resetQuery() {
      this.resetForm('queryForm')
      this.handleQuery()
    },
    reset() {
      this.form = {
        id: undefined,
        name: '',
        status: "1",
        parent_id: undefined,
        image: ''
      }
      this.resetForm('form')
    },
    cancel() {
      this.open = false
      this.reset()
    },
    handleAdd() {
      this.reset()
      this.parentOptions = this.getTopLevelOptions()
      this.open = true
      this.title = '新增分类'
    },
    handleUpdate(row) {
      const targetId = row?.id ?? this.ids[0]
      if (!targetId) {
        this.$modal.msgWarning('请选择要修改的分类')
        return
      }
      const record = this.flattenCategories(this.categoryList).find(item => String(item.id) === String(targetId))
      if (!record) {
        this.$modal.msgWarning('未找到对应的分类数据')
        return
      }
      this.form = {
        id: record.id,
        name: record.name,
        status: String(record.status ?? '0'),
        parent_id: record.parent_id != null ? record.parent_id : null,
        image: Array.isArray(record.image) ? record.image.join(',') : (record.image || '')
      }
      this.$nextTick(() => {
        if (this.$refs.form && this.$refs.form.clearValidate) {
          this.$refs.form.clearValidate()
        }
      })
      this.parentOptions = this.getTopLevelOptions(record.id)
      this.open = true
      this.title = '修改分类'
    },
    submitForm() {
      this.$refs.form.validate(valid => {
        if (!valid) {
          return
        }
        this.submitLoading = true
        const payload = {
          ...this.form,
          status: this.form.status === undefined || this.form.status === null ? undefined : Number(this.form.status),
          parent_id: this.form.parent_id === '' || this.form.parent_id === undefined ? null : Number(this.form.parent_id),
          image: this.form.image || ''
        }
        const request = payload.id ? updateCategory(payload) : addCategory({ ...payload, id: undefined })
        request
          .then(() => {
            this.$modal.msgSuccess(payload.id ? '修改成功' : '新增成功')
            this.open = false
            this.getList()
          })
          .finally(() => {
            this.submitLoading = false
          })
      })
    },
    handleSelectionChange(selection) {
      this.ids = selection.map(item => item.id)
      this.single = selection.length !== 1
      this.multiple = selection.length === 0
    },
    getTopLevelOptions(excludeId) {
      return this.categoryList
        .filter(item => {
          if (excludeId === undefined || excludeId === null) {
            return true
          }
          return String(item.id) !== String(excludeId)
        })
        .map(item => ({ label: item.name, value: item.id }))
    },
    getStatusLabel(value) {
      const target = this.statusOptions.find(item => String(item.value) === String(value))
      return target ? target.label : '-'
    },
    getStatusTagType(value) {
      const match = String(value)
      if (match === '1') {
        return 'success'
      }
      if (match === '2') {
        return 'danger'
      }
      if (match === '3') {
        return 'warning'
      }
      return 'default'
    },
    normalizeImages(value) {
      if (!value) {
        return []
      }
      const list = Array.isArray(value) ? value : String(value).split(',')
      return list
        .map(item => (item || '').trim())
        .filter(Boolean)
        .map(url => {
          if (/^https?:\/\//i.test(url)) {
            return url
          }
          if (this.baseUrl && url.startsWith(this.baseUrl)) {
            return url
          }
          if (this.baseUrl) {
            const prefix = this.baseUrl.endsWith('/') ? this.baseUrl.slice(0, -1) : this.baseUrl
            const path = url.startsWith('/') ? url : `/${url}`
            return `${prefix}${path}`
          }
          return url
        })
    }
  }
}
</script>

<style scoped lang="scss">
.image-preview {
  display: flex;
  align-items: center;
}

.image-preview__item {
  width: 48px;
  height: 48px;
  border-radius: 4px;
  overflow: hidden;
  margin-right: 6px;
}

.image-preview__more {
  font-size: 12px;
  color: #909399;
}
</style>